﻿using javax.xml.transform;
using javax.xml.transform.stream;
using net.sf.saxon;
using net.sf.saxon.query;

namespace Homework4
{
    public static class XQuery
    {
        public const string Query1 = 
@"<output>
{
for $i in //instructors/instructor 
order by $i/last return 
<instructor>
    { $i/first }
    { $i/middle }
    { $i/last }
    { $i/office/phone }
</instructor>
}
</output>";

        public const string Query2 = 
@"<html>
<body>
{
    for $i in //instructors/instructor 
    order by $i/last return
    <p>
    <b> { $i/first/text() }&#32;{ $i/middle/text() }&#32;{ $i/last/text() }</b>&#32;<i> { $i/office/phone/text() } </i>
    </p>
}
</body>
</html>";

        public const string Query3 = 
@"<output>
{
for $i in //instructors/instructor
where some $t in $i/titles satisfies ( contains(lower-case($t), ""associate professor"") )
and contains(lower-case($i/degree/type), ""ph.d."")
and $i/degree/year > 1990
order by $i/last return
<instructor>
    { $i/first }
    { $i/middle }
    { $i/last }
    { $i/interests }
    { $i/email }
</instructor>
}
</output>";

        public const string Query4 = 
@"<output>
{
for $i in //instructors/instructor
where 
(
    some $int in $i/interests satisfies
    (
        contains(lower-case($int), ""artificial intelligence"") 
        or contains(lower-case($int), ""databases"")
    )
) 
and
(
    some $ti in $i/titles/title satisfies ( lower-case($ti) = ""professor"" )
)
order by $i/last return
<instructor>
    { $i/first }
    { $i/middle }
    { $i/last }
    { $i/titles }
    { $i/interests }
    { $i/courses }
</instructor>
}
</output>";

        public const string Query5 = 
@"<output>
{
for $c in //instructors/instructor/courses/course
where some $pre in $c/prerequisites satisfies contains(lower-case($pre), ""cse 310"")
return $c
}
</output>";

        public const string Query6 = 
@"<output>
{
for $i in //instructors/instructor
where some $c in $i/courses/course satisfies ( lower-case($c/name) = ""database management"" )
and contains(lower-case($i/degree/type), ""ph.d."")
and contains(lower-case($i/degree/school), ""university of maryland"")
order by $i/last return
<instructor>
    { $i/first }
    { $i/middle }
    { $i/last }
    { $i/office }
</instructor>
}
</output>";

        public enum OutputType
        {
            Text = 0,
            Xml,
            Html
        }

        /// <summary>
        /// Runs a given XQuery against the given XML file
        /// </summary>
        public static void PerformQuery(string query, string inputFilePath, OutputType outputType, string outputFileName)
        {
            var conf = new Configuration();
            var sqc = conf.newStaticQueryContext();
            var exp = sqc.compileQuery(query);

            var dynCont = new DynamicQueryContext(conf);
            dynCont.setContextItem(conf.buildDocument(new StreamSource(inputFilePath)));

            var props = new java.util.Properties();
            props.setProperty(OutputKeys.METHOD, outputType.ToString().ToLower());
            props.setProperty(OutputKeys.INDENT, "yes");
            var ext = outputType == OutputType.Text
                          ? ".txt"
                          : outputType == OutputType.Xml
                                ? ".xml"
                                : ".html";

            exp.run(dynCont, new StreamResult(outputFileName + ext), props);
        }
    }
}
